﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

namespace DDD.Extensions
{
    public static class SwaggerExtension
    {
        public static IServiceCollection AddDefaultSwagger(this IServiceCollection services, string version, string title, Assembly assembly, string description = "")
        {
            services.AddEndpointsApiExplorer();
            services.AddTransient<IConfigureOptions<SwaggerGenOptions>, SwaggerConfigureOptions>()
                .AddSwaggerGen(options =>
            {
                options.SwaggerDoc(version, new OpenApiInfo
                {
                    Version = version,
                    Title = title,
                    Description = description
                });
                var xmlFilename = $"{assembly.GetName().Name}.xml";
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
            });

            return services;
        }

        public static WebApplication UseDefaultSwaggerUI(this WebApplication webApplication)
        {
            webApplication.UseSwagger();
            webApplication.UseSwaggerUI(options =>
            {
                var apiDescriptionGroups = webApplication.Services.GetRequiredService<IApiDescriptionGroupCollectionProvider>().ApiDescriptionGroups.Items;
                foreach (var description in apiDescriptionGroups)
                {
                    options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName);
                }
            });

            return webApplication;
        }

        internal class SwaggerConfigureOptions : IConfigureOptions<SwaggerGenOptions>
        {
            private readonly IApiDescriptionGroupCollectionProvider _provider = null;

            public SwaggerConfigureOptions(IApiDescriptionGroupCollectionProvider provider)
            {
                _provider = provider;
            }

            public void Configure(SwaggerGenOptions options)
            {
                foreach (var description in _provider.ApiDescriptionGroups.Items)
                {
                    options.SwaggerDoc(description.GroupName, null);
                }
            }
        }
    }
}
